﻿let flowObj
let oPolyLine
let pointsNum = ''
let IsNode = false
const topheight = 42
const isFlowDrawReadonly = false
$(document).ready(function() {
  flowObj = new FlowDraw()
  /// 创建节点事件
  flowObj.CreateNodeEvent = null
  flowObj.DelNodeEvent = null
  flowObj.SelectEvent = function(node) {
    if (queryUrlParam('view') == '1') {
      return
    }
    $('#resLeftFilterWrap').show()
    if ($('#flowNodeInfo').is(':hidden')) {
      $('#flowNodeInfo').show()
      $('#flowBaseInfo').hide()
      $('#cheackErrorMsg').hide()
    }
    flowdataObj.SelectNode($(node).attr('id'))
  }
})
/// 流程绘画对象
function FlowDraw() {
  this.SelectButtonType = ''
  this.CanvasDraw = $('#svg1') /// 布画对象
  this.CanvasPane = $('#DivFlowData')

  this.CanvasDraw.height(this.CanvasPane.height())
  this.SelectObject = null
  this.MouseoverNode = null /// 鼠标移入节点时  该对象会赋值 移出会为空
  this.SelectEvent = null /// 单机选中节点扩展方法
  this.OldSelectObject = null
  this.CreateLineEvent = null /// 创建连线事件
  this.ChangedLineEvent = null /// /更改连线事件
  this.SelectLineEvent = null /// 选中连线事件
  this.Init()
}
/// 初始化
FlowDraw.prototype.Init = function() {
  $(document).mousedown(function(e) {
    if (queryUrlParam('view') == '1') {
      return
    }
    if (isFlowDrawReadonly == true) {
      return
    }
    if (
      $(window.event.srcElement.outerHTML).attr('SubsidiaryID') != undefined
    ) {
      return
    }
    const cotrolID = $(window.event.srcElement)
      .parents('span')
      .attr('id')
    if (
      'btnBottomSnap,btnTopSnap,btnRightSnap,btnLeftSnap'.indexOf(cotrolID) >= 0
    ) {
      return
    }
    if (flowObj.SelectButtonType == 'MultipleSelect') {
      const toolbars = $(window.event.srcElement).parents('.toolbars')
      if (toolbars.length != 0) {
        return
      }
      var contorl = $(window.event.srcElement).parents('[nodeType]')
      if (contorl.length == 0) {
        flowObj.SelectButtonType = ''
        selectChangedObject = []
        $('rect').remove()
        return
      }
      let isChanged = false
      for (let idex = 0; idex < selectChangedObject.length; idex++) {
        if ($(selectChangedObject[idex]).attr('id') == $(contorl).attr('id')) {
          isChanged = true
        }
      }
      if (!isChanged) {
        flowObj.SelectButtonType = ''
        selectChangedObject = []
        $('rect').remove()
      }
    } else if (flowObj.SelectButtonType == '') {
      var contorl = $(window.event.srcElement).parents('[nodeType]')
      if (contorl.length == 0) {
        if ($(window.event.srcElement).prop('tagName') == 'polyline') {
          $('rect').remove()
          flowObj.SelectButtonType = ''
          selectChangedObject = []
          flowObj.SelectObject = window.event.srcElement
          if (queryUrlParam('view') != '1') {
            flowObj.CreateLineSubsidiary(window.event.srcElement)
          }
          if (typeof flowObj.SelectLineEvent === 'function') {
            flowObj.SelectLineEvent(window.event.srcElement)
          }
          return
        }
        if ($(window.event.srcElement).parents('#DivFlowData').length == 0) {
          return
        }
        flowObj.SelectButtonType = ''
        selectChangedObject = []
        flowObj.SelectObject = null
        $('rect').remove()
        return
      }
      if ($(flowObj.SelectObject).attr('id') != $(contorl).attr('id')) {
        flowObj.SelectButtonType = ''
        selectChangedObject = []
        flowObj.SelectObject = null
        $('rect').remove()
      }
    }
  })
  this.NodeBindEvent($('#F_Start'))
  this.NodeBindEvent($('#F_End'))
  const $this = this
  this.CanvasPane.mousedown(function(ev) {
    if (isFlowDrawReadonly == true) {
      return
    }
    $this.CanvasMousedown(ev)
  })
  this.CanvasDraw.mousedown(function(ev) {
    if (queryUrlParam('view') == '1') {
      return
    }
    $('#resLeftFilterWrap').show()
    if ($('#flowBaseInfo').is(':hidden')) {
      $('#flowBaseInfo').show()
      $('#flowNodeInfo').hide()
      $('#cheackErrorMsg').hide()
      $this.OldSelectObject = null
    }
  })
}
/// 创建对象
FlowDraw.prototype.createTag = function(tagName, tagAttr) {
  const ming = 'http://www.w3.org/2000/svg'
  const tag = document.createElementNS(ming, tagName)
  for (const attr in tagAttr) {
    tag.setAttribute(attr, tagAttr[attr])
  }
  $(tag).css('cursor', 'pointer')
  return tag
}
/// 单击布画事件
FlowDraw.prototype.CanvasMousedown = function(ev) {
  if (queryUrlParam('view') == '1') {
    return
  }
  if (this.SelectButtonType == '') {
    // if(this.SelectObject.tagName=="polyline"){
    //    if(!IsNode)
    //    {
    //        this.SelectObject.remove();
    //        $this.CanvasDraw.unbind("mousemove");

    //    }
    // }
    return
  }
  const $this = this
  /// 当前选择的是 子流 节点，合流，分流时  点击对应的布画 创建一个节点
  if ('SubFlow,Node,HL,FL'.indexOf(this.SelectButtonType) >= 0) {
    $('rect').remove()
    var obj = this.CanvasPane[0]
    const x = ev.clientX - obj.offsetLeft - 16
    const y = ev.clientY - obj.offsetTop - topheight - 16
    let img = 'DrawNode.gif'
    switch (this.SelectButtonType) {
      case 'SubFlow':
        img = 'DrawSubFlow.gif'
        break
      case 'Node':
        img = 'DrawNode.gif'
        break
      case 'HL':
        img = 'DrawHL.gif'
        break
      case 'FL':
        img = 'DrawFL.gif'
        break
    }
    var obj = $(
      "<div nodeType='" +
        this.SelectButtonType +
        "' id='F_" +
        this.GetID() +
        "' caption='' style='cursor:pointer; position:absolute;z-index:103;left:" +
        x +
        'px;top:' +
        y +
        "px;width:38px;' stroked='f' strokecolor='#000000' strokeweight='1px'  selected='false' ></div>"
    )
    obj.html(
      "<TABLE id='t_" +
        obj.attr('id') +
        '\' cellSpacing=0 cellPadding=0 width="100%" height="100%" border=0><tr height=38px><td Align=center id=\'Image' +
        obj.attr('id') +
        "' class='node'>&nbsp;</td></tr></TABLE><div style='font-size: 11px;position: relative;width: 60px;left: -10px;' id='Text" +
        obj.attr('id') +
        "' align='center'>环节</div>"
    )
    this.CanvasPane.append(obj)
    this.NodeBindEvent(obj, ev)
    /// 创建节点事件为函数 每创建一个节点 进行调用
    if (typeof this.CreateNodeEvent === 'function') {
      this.CreateNodeEvent(obj)
    }
  }
  if (this.SelectButtonType == 'Line') {
    if (oPolyLine != null) {
      if (!IsNode) {
        $(oPolyLine).remove()
        $this.CanvasPane.unbind('mousemove')
        oPolyLine = null
        pointsNum = ''
      }
    }
  }
}
FlowDraw.prototype.MultipleSelectMove = function(
  e,
  distenceX,
  distenceY,
  contorl
) {
  if (queryUrlParam('view') == '1') {
    return
  }
  const $this = this
  if ($this.SelectButtonType != 'MultipleSelect') {
    return
  }
  let IsMove = false
  for (var idex = 0; idex < selectChangedObject.length; idex++) {
    if ($(contorl).attr('id') == $(selectChangedObject[idex]).attr('id')) {
      IsMove = true
      break
    }
  }
  if (!IsMove) return
  let pageY = e.pageY
  /// 控制拖拽 不能拖拽到布画外面了
  if (pageY < topheight + 20) {
    pageY = topheight + 20
  }
  let x = e.pageX - distenceX
  let y = pageY - distenceY - topheight

  if (x < 0) {
    x = 0
  } else if (x > $(document).width() - $(contorl).outerWidth(true)) {
    x = $(document).width() - $(contorl).outerWidth(true)
  }
  if (y < 0) {
    y = 0
  } else if (y > $(document).height() - $(contorl).outerHeight(true)) {
    y = $(document).height() - $(contorl).outerHeight(true)
  }
  const oldx = $(contorl).position().left
  const oldy = $(contorl).position().top
  const mousemoveX = Number(oldx) - Number(x)
  const mousemovey = Number(oldy) - Number(y)
  // $(contorl).css({
  //    'left': x + 'px',
  //    'top': y + 'px'
  // });
  for (var idex = 0; idex < selectChangedObject.length; idex++) {
    // if ($(contorl).attr("id") == $(selectChangedObject[idex]).attr("id"))
    //    continue;
    const cotrolItem = $(selectChangedObject[idex])
    if (cotrolItem[0].attributes.nodeType.value == 'Line') {
      var points = cotrolItem
        .attr('points')
        .replace(/ /g, ',')
        .split(',')
      for (var li = 0; li < points.length / 2; li++) {
        const left = points[li * 2]
        const top = points[li * 2 + 1]
        points[li * 2] = Number(left) - mousemoveX
        points[li * 2 + 1] = Number(top) - mousemovey
      }
      cotrolItem[0].setAttribute('points', points.join(','))
      $("[SubsidiaryID='" + $(cotrolItem).attr('id') + "']").each(function() {
        const x = $(this).attr('x')
        const y = $(this).attr('y')
        $(this).attr('x', Number(x) - mousemoveX)
        $(this).attr('y', Number(y) - mousemovey)
      })
    } else {
      const itemposition = $(cotrolItem).position()
      $(cotrolItem).css({
        left: Number(itemposition.left) - mousemoveX + 'px',
        top: Number(itemposition.top) - mousemovey + 'px'
      })
      $("[SubsidiaryID='" + $(cotrolItem).attr('id') + "']").each(function() {
        const x = $(this).attr('x')
        const y = $(this).attr('y')
        $(this).attr('x', Number(x) - mousemoveX)
        $(this).attr('y', Number(y) - mousemovey)
      })
      const LineStart = $("[startNode='" + $(cotrolItem).attr('id') + "']")
      for (var li = 0; li < LineStart.length; li++) {
        var item = LineStart[li]
        if (selectIds.indexOf($(item).attr('id')) >= 0) {
          continue
        }
        var points = item.attributes.points.value.replace(/ /g, ',').split(',')
        points[0] = Number(itemposition.left) - mousemoveX + 19
        points[1] = Number(itemposition.top) - mousemovey + 19
        if (points.length == 4) {
          var position = $this.DistanceObj(
            $(cotrolItem).attr('id'),
            item.attributes.endNode.value
          )
          points[points.length - 2] = position.x
          points[points.length - 1] = position.y
        }
        item.setAttribute('points', points.join(','))
      }
      const LineEnd = $("[endNode='" + $(cotrolItem).attr('id') + "']")
      for (var li = 0; li < LineEnd.length; li++) {
        var item = LineEnd[li]
        if (selectIds.indexOf($(item).attr('id')) >= 0) {
          continue
        }
        var points = item.attributes.points.value.replace(/ /g, ',').split(',')
        var position = $this.Distance(
          { x: points[points.length - 4], y: points[points.length - 3] },
          $(cotrolItem).attr('id')
        )
        points[points.length - 2] = position.x
        points[points.length - 1] = position.y
        item.setAttribute('points', points.join(','))
      }
    }
  }
}
/// /绑定节点事件
FlowDraw.prototype.NodeBindEvent = function(NodeObj, ev) {
  const $this = this
  const obj = NodeObj
  NodeObj.mousedown(function(e) {
    if ($this.SelectButtonType == 'MultipleSelect') {
      var contorl = $(this)
      if (contorl.length == 0) {
        $this.SelectButtonType = ''
        selectChangedObject = []
        $('rect').remove()
      } else {
        let isChanged = false
        for (let idex = 0; idex < selectChangedObject.length; idex++) {
          if (
            $(selectChangedObject[idex]).attr('id') == $(contorl).attr('id')
          ) {
            isChanged = true
          }
        }
        if (!isChanged) {
          $this.SelectButtonType = ''
          selectChangedObject = []
          $('rect').remove()
        }
      }
    }
    if ($this.SelectButtonType == '') {
      $this.SelectObject = this
      if ($("[SubsidiaryID='" + $(this).attr('id') + "']").length == 0) {
        $('rect').remove()
      }
      var x = $(this).position()
      var contorl = this
      if (queryUrlParam('view') != '1') {
        $this.CreateNodeSubsidiary(contorl)
      }
      /// /实现拖拽节点
      // e.pageX
      var positionDiv = $(this).offset()
      var distenceX = e.pageX - positionDiv.left
      var distenceY = e.pageY - positionDiv.top
      flowdrawdraging = false
      setTimeout('flowdrawdraging=true', 200) // 延迟200毫秒以区分时单机节点和拖拽节点的事件
      $(document).mousemove(function(e) {
        if (queryUrlParam('view') == '1') {
          return
        }
        if (flowdrawdraging) {
          $this.MultipleSelectMove(e, distenceX, distenceY, contorl)
          $this.Move(e, distenceX, distenceY, contorl)
        }
      })
      $(document).mouseup(function() {
        if (queryUrlParam('view') == '1') {
          return
        }
        if ($this.SelectButtonType != '') {
          return
        }
        $(document).off('mousemove')
      })
      if ($this.OldSelectObject != $this.SelectObject) {
        $this.OldSelectObject = $this.SelectObject
        if (
          $this.SelectEvent != null &&
          typeof $this.SelectEvent === 'function'
        ) {
          $this.SelectEvent($this.SelectObject)
        }
      }
    } else if ($this.SelectButtonType == 'Line') {
      var obj = $this.CanvasPane[0]
      if (!oPolyLine) {
        var contorl = this
        var position = $(this).position()
        if ($(contorl).attr('id') == 'F_End') {
          return
        }
        oPolyLine = $this.createTag('polyline', {
          fill: 'none',
          stroke: '#3892D3',
          'stroke-width': '2',
          nodeType: $this.SelectButtonType,
          startNode: $(contorl).attr('id'),
          'marker-end': 'url(#markerArrow)', /// 目前IE不兼容 这种方式  IE的情况需要注释
          id: $this.GetID()
        })
        $this.CanvasDraw.append(oPolyLine)

        var x = position.left + 19
        var y = position.top + 19

        if (pointsNum == '') {
          pointsNum = x + ',' + y
        } else {
          pointsNum += ',' + x + ',' + y
        }

        oPolyLine.setAttribute('points', pointsNum)
        $(oPolyLine).click(function() {
          if (queryUrlParam('view') == '1') {
            return
          }
          if ($this.SelectButtonType == 'MultipleSelect') {
            const contorl = $(this)
            if (contorl.length == 0) {
              $this.SelectButtonType = ''
              selectChangedObject = []
              $('rect').remove()
            } else {
              let isChanged = false
              for (let idex = 0; idex < selectChangedObject.length; idex++) {
                if (
                  $(selectChangedObject[idex]).attr('id') ==
                  $(contorl).attr('id')
                ) {
                  isChanged = true
                }
              }
              if (!isChanged) {
                $this.SelectButtonType = ''
                selectChangedObject = []
                $('rect').remove()
              }
            }
          }

          if ($("[SubsidiaryID='" + $(this).attr('id') + "']").length == 0) {
            $('rect').remove()
          }
          if (queryUrlParam('view') != '1') {
            $this.CreateLineSubsidiary(this)
          }
          // $("polyline").attr("stroke", "#3892D3");
          // $("polyline").attr("marker-end", "url(#selectmarker)");
          // $(this).attr("stroke", "red");
          // this.setAttribute("marker-end", "url(#selectmarker)");
        })

        if (ev != undefined && ev.button === 2) {
          /// // $this.NodeBindEvent(obj, ev);  新增连线后 再拖动的问题解决 需要分析NodeBindEvent方法
          $this.CanvasPane.unbind('mousemove')
          $this.CanvasPane.contextmenu(function() {
            $this.CanvasPane.onmousemove = null
            return false
          })
        } else {
          $this.CanvasPane.mousemove(function(ev) {
            if (queryUrlParam('view') == '1') {
              return
            }
            var ev = ev || window.event

            if (oPolyLine) {
              const x = ev.clientX - obj.offsetLeft
              const y = ev.clientY - obj.offsetTop - topheight
              oPolyLine.setAttribute('points', pointsNum + ',' + x + ',' + y)
            }
          })
        }
      } else {
        var obj = $this.CanvasPane[0]
        var contorl = this
        if ($(contorl).attr('id') == 'F_Start') {
          return
        }
        var position = $(this).position()
        oPolyLine.setAttribute('endNode', $(contorl).attr('id'))
        //   $(oPolyLine).attr("endNode",$(contorl).attr("id"));
        var position = $this.DistanceObj(
          oPolyLine.attributes.startNode.value,
          $(contorl).attr('id')
        )
        var x = position.x
        var y = position.y
        if (pointsNum == '') {
          pointsNum = x + ',' + y
        } else {
          pointsNum += ',' + x + ',' + y
        }
        oPolyLine.setAttribute('points', pointsNum)
        $this.CanvasPane.unbind('mousemove')
        if (typeof $this.CreateLineEvent === 'function') {
          $this.CreateLineEvent(oPolyLine)
        }
        oPolyLine = null
        pointsNum = ''
      }
    } else if ($this.SelectButtonType == 'MultipleSelect') {
      var x = $(this).position()
      var contorl = this
      /// /实现拖拽节点
      // e.pageX
      var positionDiv = $(this).offset()
      var distenceX = e.pageX - positionDiv.left
      var distenceY = e.pageY - positionDiv.top

      $(document).mousemove(function(e) {
        if (queryUrlParam('view') == '1') {
          return
        }
        $this.MultipleSelectMove(e, distenceX, distenceY, contorl)
        $this.Move(e, distenceX, distenceY, contorl)
      })
      $(document).mouseup(function() {
        if (queryUrlParam('view') == '1') {
          return
        }
        if ($this.SelectButtonType != 'MultipleSelect') {
          return
        }
        $(document).off('mousemove')
      })
    }
  })
  NodeObj.mouseover(function() {
    if (queryUrlParam('view') == '1') {
      return
    }
    /// 鼠标移入到节点事件
    if ($this.SelectButtonType == 'Line') {
      IsNode = true
    }
    if ($this.SelectObject != null) {
      if (
        $this.SelectObject.nodeName == 'polyline' &&
        $this.SelectButtonType == ''
      ) {
        $this.MouseoverNode = this
        IsNode = true
      }
    }
  }).mouseout(function() {
    if (queryUrlParam('view') == '1') {
      return
    }
    if ($this.SelectButtonType == 'Line') {
      IsNode = false
    }
    if ($this.SelectObject != null) {
      if (
        $this.SelectObject != null &&
        $this.SelectObject.nodeName == 'polyline' &&
        $this.SelectButtonType == ''
      ) {
        IsNode = false
        $this.MouseoverNode = null
      }
    }
  })
}

FlowDraw.prototype.Move = function(e, distenceX, distenceY, contorl) {
  if (queryUrlParam('view') == '1') {
    return
  }
  const $this = this
  if ($this.SelectButtonType != '') {
    return
  }
  /// 控制拖拽 不能拖拽到布画外面了
  let pageY = e.pageY
  if (pageY < topheight + 20) {
    pageY = topheight + 20
  }
  let x = e.pageX - distenceX
  let y = pageY - distenceY
  if (x < 0) {
    x = 0
  } else if (x > $(document).width() - $(contorl).outerWidth(true)) {
    x = $(document).width() - $(contorl).outerWidth(true)
  }
  if (y < 0) {
    y = 0
  } else if (y > $(document).height() - $(contorl).outerHeight(true)) {
    y = $(document).height() - $(contorl).outerHeight(true)
  }
  y = y - topheight
  $(contorl).css({
    left: x + 'px',
    top: y + 'px'
  })
  const controlID = $(contorl).attr('id')
  const SubsidiaryList = $("[SubsidiaryID='" + controlID + "']")
  for (let si = 0; si < SubsidiaryList.length; si++) {
    const item = SubsidiaryList[si]
    switch (item.attributes.typeSubsidiary.value) {
      case 'top':
        $(item).attr('x', x + 16.5)
        $(item).attr('y', y - 5)
        break
      case 'down':
        $(item).attr('x', x + 16.5)
        $(item).attr('y', y + 38)
        break
      case 'left':
        $(item).attr('x', x - 5)
        $(item).attr('y', y + 19)
        break
      case 'right':
        $(item).attr('x', x + 38)
        $(item).attr('y', y + 19)
        break
    }
  }
  this.MoveNodeLine(controlID, x, y)
  // var LineStart = $("[startNode='" + controlID + "']");
  // for (var li = 0; li < LineStart.length; li++) {
  //    var item = LineStart[li];
  //    var points = item.attributes['points'].value.replace(/ /g, ",").split(',');
  //    points[0] = x + 19;
  //    points[1] = y - 76 + 19;
  //    if (points.length == 4) {
  //        var position = $this.DistanceObj(controlID, item.attributes["endNode"].value);
  //        points[points.length - 2] = position.x;
  //        points[points.length - 1] = position.y;
  //    }
  //    item.setAttribute('points', points.join(','));
  // }
  // var LineEnd = $("[endNode='" + controlID + "']");
  // for (var li = 0; li < LineEnd.length; li++) {
  //    var item = LineEnd[li];
  //    var points = item.attributes['points'].value.replace(/ /g, ",").split(',');
  //    var position = $this.Distance({ x: points[points.length - 4], y: points[points.length - 3] }, controlID);
  //    points[points.length - 2] = position.x;
  //    points[points.length - 1] = position.y;
  //    item.setAttribute('points', points.join(','));
  // }
}
/// 获取一个新的唯一ID
FlowDraw.prototype.GetID = function() {
  return Number(
    Math.random()
      .toString()
      .substr(3, length) + Date.now()
  ).toString(36)
}
/// 拖拽切分点方法
FlowDraw.prototype.Drag = function(oCircle) {
  if (queryUrlParam('view') == '1') {
    return
  }
  const $this = this
  let IsDrag = false
  $(oCircle).mousedown(function(e) {
    if (queryUrlParam('view') == '1') {
      return
    }
    const positionDiv = $(this).offset()
    const distenceX = e.pageX - positionDiv.left
    const distenceY = e.pageY - positionDiv.top
    $(document).mousemove(function(e) {
      if (queryUrlParam('view') == '1') {
        return
      }
      IsDrag = true
      let x = e.pageX - distenceX
      let y = e.pageY - distenceY - topheight
      if (x < 0) {
        x = 0
      } else if (x > $(document).width() - $(oCircle).outerWidth(true)) {
        x = $(document).width() - $(oCircle).outerWidth(true)
      }
      if (y < 0) {
        y = 0
      } else if (y > $(document).height() - $(oCircle).outerHeight(true)) {
        y = $(document).height() - $(oCircle).outerHeight(true)
      }
      $(oCircle).attr('x', x)
      $(oCircle).attr('y', y)
      const line = $('#' + oCircle.attributes.SubsidiaryID.value)
      const index = Number(oCircle.attributes.index.value) // $(oCircle).attr("Index");

      const points = line
        .attr('points')
        .replace(/ /g, ',')
        .split(',')
      if (oCircle.attributes.rectIsMiddle.value == '0') {
        points[index * 2] = x
        points[index * 2 + 1] = y
        if (points.length / 2 - index == 2) {
          /// 当是倒数第二点时 拖拽 需要计算节点四个点 最近的一个点是哪个 并将其移动
          const startP = { x, y }
          const newp = $this.Distance(startP, line[0].attributes.endNode.value)
          points[(points.length / 2 - 1) * 2] = newp.x
          points[(points.length / 2 - 1) * 2 + 1] = newp.y
          const rectList = $('rect')
          for (let rectIdex = 0; rectIdex < rectList.length; rectIdex++) {
            const rectItem = rectList[rectIdex]
            const itemIndex = Number(rectItem.attributes.index.value)
            if (itemIndex == points.length / 2 - 1) {
              $(rectItem).attr('x', newp.x)
              $(rectItem).attr('y', newp.y)
            }
          }
        }
        line.attr('points', points.join(','))
      } else {
        const newpoints = []
        for (var i = 0; i < points.length; i++) {
          if (i / 2 == Number(index) + 1) {
            newpoints.push(x)
            newpoints.push(y)
          }
          newpoints.push(points[i])
        }

        const circleList = $(
          "[SubsidiaryID='" + oCircle.attributes.SubsidiaryID.value + "']"
        )
        for (var i = 0; i < circleList.length; i++) {
          const item = circleList[i]
          if (item.attributes.rectIsMiddle.value == '0') {
            const itemindex = item.attributes.index.value
            if (itemindex > Number(index)) {
              item.setAttribute('index', Number(itemindex) + 1)
            }
          }
        }
        oCircle.setAttribute('rectIsMiddle', '0')
        oCircle.setAttribute('index', Number(index) + 1)
        line.attr('points', newpoints.join(','))
      }
    })
    $(document).mouseup(function() {
      if (queryUrlParam('view') == '1') {
        return
      }
      if (
        $this.SelectObject != null &&
        $this.SelectObject.nodeName == 'polyline' &&
        IsDrag
      ) {
        const line = $('#' + oCircle.attributes.SubsidiaryID.value)
        const index = parseInt(oCircle.attributes.index.value)
        const points = line
          .attr('points')
          .replace(/ /g, ',')
          .split(',')
        /// 拖拽线条最后一个点 释放时必须在节点上面
        if (index * 2 + 1 == points.length - 1) {
          if (
            $this.SelectObject != null &&
            $this.SelectObject.nodeName == 'polyline' &&
            $this.SelectButtonType == '' &&
            $this.MouseoverNode != null
          ) {
            let endnodeId = $($this.MouseoverNode).attr('id')
            if (endnodeId == 'F_Start') {
              /// 如果连线流向开始节点 则取消还原回去
              endnodeId = line[0].getAttribute('endNode')
            } else {
              /// 连线更改
              if (typeof $this.ChangedLineEvent === 'function') {
                $this.ChangedLineEvent(line[0], endnodeId)
              }
            }
            var startP = { x: points[index * 2 - 2], y: points[index * 2 - 1] }
            var newp = $this.Distance(startP, endnodeId)
            points[index * 2] = newp.x
            points[index * 2 + 1] = newp.y
            $(oCircle).attr('x', newp.x)
            $(oCircle).attr('y', newp.y)
            line[0].setAttribute('endNode', endnodeId)
          } else {
            /// 对应的点没有移入节点 对应连线进行还原
            var startP = { x: points[index * 2 - 2], y: points[index * 2 - 1] }
            var newp = $this.Distance(startP, line[0].attributes.endNode.value)
            points[index * 2] = newp.x
            points[index * 2 + 1] = newp.y
            $(oCircle).attr('x', newp.x)
            $(oCircle).attr('y', newp.y)
          }
          line.attr('points', points.join(','))
        } else {
          const y1 = points[(index - 1) * 2 + 1]
          const y2 = points[index * 2 + 1]
          const y3 = points[(index + 1) * 2 + 1]
          const x1 = points[(index - 1) * 2]
          const x2 = points[index * 2]
          const x3 = points[(index + 1) * 2]
          const l1 = (y3 - y1) / (x3 - x1)
          const l2 = (y2 - y1) / (x2 - x1)
          if (l1 - l2 > -0.05 && l1 - l2 < 0.05) {
            points.splice(index * 2, 2)
          }
          $this.SelectObject.setAttribute('points', points.join(','))
        }
        $('rect').remove()
        if (queryUrlParam('view') != '1') {
          $this.CreateLineSubsidiary(line[0])
        }
      }
      IsDrag = false
      $(document).off('mousemove')
    })
  })
}
/// 创建 线条的切分点  传入参数true  悬浮点就不能拖拽  IsDel等于true 是代表先删除控件悬浮点 然后创建新的
FlowDraw.prototype.CreateLineSubsidiary = function($thisline, Isbool, IsDel) {
  if (oPolyLine == null) {
    $this = this
    if (IsDel == true) {
      $("[SubsidiaryID='" + $thisline.attr('id') + "']").remove()
    }
    $this.SelectObject = $thisline
    const strpoints = $($thisline).attr('points')
    const points = strpoints.replace(/ /g, ',').split(',')
    const movestr = Isbool == true ? '' : 'cursor:move'
    let uppoint
    for (let i = 0; i < points.length / 2; i++) {
      var oCircle = $this.createTag('rect', {
        x: points[i * 2] - 2.5 + (points.length / 2 - 1 == i ? 5 : 0),
        y: points[i * 2 + 1] - 2.5 + (points.length / 2 - 1 == i ? 5 : 0),
        width: '5',
        height: '5',
        fill: 'white',
        stroke: 'black',
        style: movestr,
        'stroke-width': 1,
        rectIsMiddle: 0,
        index: i,
        id: $this.GetID(),
        SubsidiaryID: $($thisline).attr('id') /// 依附对象ID
      })
      $this.CanvasDraw.append(oCircle)
      if (Isbool != true) {
        $this.Drag(oCircle)
      }
      /// 产生中间方块
      if (i != 0) {
        var oCircle = $this.createTag('rect', {
          x:
            Number(uppoint.x) + (Number(points[i * 2]) - Number(uppoint.x)) / 2,
          y:
            Number(uppoint.y) +
            (Number(points[i * 2 + 1]) - Number(uppoint.y)) / 2,
          width: '5',
          height: '5',
          fill: 'white',
          stroke: 'black',
          style: movestr,
          'stroke-width': 1,
          rectIsMiddle: 1,
          index: i - 1,
          id: $this.GetID(),
          SubsidiaryID: $($thisline).attr('id') /// 依附对象ID
        })
        $this.CanvasDraw.append(oCircle)
        if (Isbool != true) {
          $this.Drag(oCircle)
        }
      }
      uppoint = { x: points[i * 2] - 2.5, y: points[i * 2 + 1] - 2.5 }
      // }
    }
  }
}
/// 创建节点的 悬浮点  IsDel等于true 是代表先删除控件悬浮点 然后创建新的
FlowDraw.prototype.CreateNodeSubsidiary = function($thisNode, IsDel) {
  const $this = this
  const x = $($thisNode).position()
  // top
  if (IsDel == true) {
    $("SubsidiaryID='" + $($thisNode).attr('id') + "'").remove()
  }
  let orect = $this.createTag('rect', {
    x: x.left + 38 / 2 - 2.5,
    y: x.top - 5,
    width: '5',
    height: '5',
    fill: 'white',
    stroke: 'black',
    'stroke-width': 1,
    typeSubsidiary: 'top',
    id: $this.GetID(),
    SubsidiaryID: $($thisNode).attr('id') /// 依附对象ID
  })
  // down
  $this.CanvasDraw.append(orect)
  orect = $this.createTag('rect', {
    x: x.left + 38 / 2 - 2.5,
    y: x.top + 38,
    width: '5',
    height: '5',
    fill: 'white',
    stroke: 'black',

    'stroke-width': 1,
    typeSubsidiary: 'down',
    id: $this.GetID(),
    SubsidiaryID: $($thisNode).attr('id') /// 依附对象ID
  })
  $this.CanvasDraw.append(orect)
  /// left
  orect = $this.createTag('rect', {
    x: x.left - 5,
    y: x.top + 38 / 2 - 2.5,
    width: '5',
    height: '5',
    fill: 'white',
    stroke: 'black',

    'stroke-width': 1,
    typeSubsidiary: 'left',
    id: $this.GetID(),
    SubsidiaryID: $($thisNode).attr('id') /// 依附对象ID
  })
  // right
  $this.CanvasDraw.append(orect)
  orect = $this.createTag('rect', {
    x: x.left + 38,
    y: x.top + 38 / 2 - 2.5,
    width: '5',
    height: '5',
    fill: 'white',
    stroke: 'black',

    'stroke-width': 1,
    typeSubsidiary: 'right',
    id: $this.GetID(),
    SubsidiaryID: $($thisNode).attr('id') /// 依附对象ID
  })
  $this.CanvasDraw.append(orect)
}
/// 计算点到节点四个点最近距离
FlowDraw.prototype.DistanceObj = function(startID, endNodeID) {
  const startposition = $('#' + startID).position()
  return this.Distance(
    { x: startposition.left + 19, y: startposition.top + 19 },
    endNodeID
  )
}
FlowDraw.prototype.Distance = function(startposition, endNodeID) {
  function getJuLi(p1, p2) {
    return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)
  }
  const x = $('#' + endNodeID).position()
  const startp = startposition
  const left = { x: x.left - 3, y: x.top + 38 / 2 }
  const right = { x: x.left + 38 + 3, y: x.top + 38 / 2 }
  const top = { x: x.left + 38 / 2, y: x.top - 3 }
  const down = { x: x.left + 38 / 2, y: x.top + 38 + 15 }
  let current
  if (getJuLi(startp, left) >= getJuLi(startp, right)) {
    current = right
  } else {
    current = left
  }
  if (getJuLi(startp, current) >= getJuLi(startp, top)) {
    current = top
  }
  if (getJuLi(startp, current) >= getJuLi(startp, down)) {
    current = down
  }
  return current
}
/// 删除方法
FlowDraw.prototype.Delete = function(node) {
  if (queryUrlParam('view') == '1') {
    return
  }
  const nodeId = $(node).attr('id')
  /// 创建节点事件为函数 每创建一个节点 进行调用
  if (typeof this.DelNodeEvent === 'function') {
    this.DelNodeEvent(node)
  }
  if (nodeId != 'F_End' && nodeId != 'F_Start') {
    /// 移除开始节点连线
    $("[startNode='" + nodeId + "']").remove()
    // 移除结束节点连线
    $("[endNode='" + nodeId + "']").remove()
    $("[SubsidiaryID='" + nodeId + "']").remove()
    /// 移除连线或节点
    $(node).remove()
  }
}
/// 移动
FlowDraw.prototype.KeyMove = function(node, x, y) {
  if (queryUrlParam('view') == '1') {
    return
  }
  if ($(node).attr('nodetype') != undefined) {
    let nx = $(node).css('left')
    let ny = $(node).css('top')
    const nodeId = $(node).attr('id')
    nx = parseInt(nx) + x
    ny = parseInt(ny) + y
    $(node).css('left', nx + 'px')
    $(node).css('top', ny + 'px')
    $("[SubsidiaryID='" + nodeId + "']").each(function() {
      const sx = $(this).attr('x')
      const sy = $(this).attr('y')
      $(this).attr('x', parseInt(sx) + x)
      $(this).attr('y', parseInt(sy) + y)
    })
    this.MoveNodeLine(nodeId, nx, ny)
  } else if (node[0].nodeName == 'polyline') {
    const points = node[0].attributes.points.value.replace(/ /g, ',').split(',')
    if (points.length > 4) {
      const count = points.length / 2 - 1
      for (let i = 1; i < count; i++) {
        points[i * 2] = parseInt(points[i * 2]) + x
        points[i * 2 + 1] = parseInt(points[i * 2 + 1]) + y
      }
      node[0].setAttribute('points', points.join(','))
    }
    if (queryUrlParam('view') != '1') {
      this.CreateLineSubsidiary(node, '', true)
    }
  }
}
FlowDraw.prototype.MoveNodeLine = function(nodeId, nx, ny) {
  if (queryUrlParam('view') == '1') {
    return
  }
  const LineStart = $("[startNode='" + nodeId + "']")
  for (var li = 0; li < LineStart.length; li++) {
    var item = LineStart[li]
    var points = item.attributes.points.value.replace(/ /g, ',').split(',')
    points[0] = nx + 19
    points[1] = ny + 19
    if (points.length == 4) {
      var position = this.Distance(
        { x: points[0], y: points[1] },
        item.attributes.endNode.value
      )
      points[points.length - 2] = position.x
      points[points.length - 1] = position.y
    }
    item.setAttribute('points', points.join(','))
  }
  const LineEnd = $("[endNode='" + nodeId + "']")
  for (var li = 0; li < LineEnd.length; li++) {
    var item = LineEnd[li]
    var points = item.attributes.points.value.replace(/ /g, ',').split(',')
    var position = this.Distance(
      { x: points[points.length - 4], y: points[points.length - 3] },
      nodeId
    )
    points[points.length - 2] = position.x
    points[points.length - 1] = position.y
    item.setAttribute('points', points.join(','))
  }
}
FlowDraw.prototype.SaveDrawJson = function() {
  const flowDrawJson = {}
  flowDrawJson.NodeList = []
  flowDrawJson.LineList = []
  $('[nodeType]').each(function() {
    if ($(this).attr('nodeType') == undefined) {
      const lineItem = {}
      lineItem.nodeType = this.attributes.nodeType.value // $(this).attr("nodeType");
      lineItem.lineId = this.attributes.id.value // $(this).attr("id");
      lineItem.startNode = this.attributes.startNode.value // $(this).attr("startNode");
      lineItem.endNode = this.attributes.endNode.value // $(this).attr("endNode");
      lineItem.points = this.attributes.points.value
      $(this).attr('points')
      flowDrawJson.LineList.push(lineItem)
    } else {
      const nodeItem = {}
      nodeItem.nodeType = $(this).attr('nodeType')
      nodeItem.nodeId = $(this).attr('id')
      nodeItem.nodeX = $(this).css('left')
      nodeItem.nodeY = $(this).css('top')
      nodeItem.nodeText = $(this)
        .find('#Text' + nodeItem.nodeId)
        .text()
      flowDrawJson.NodeList.push(nodeItem)
    }
  })
  return flowDrawJson
}
FlowDraw.prototype.LoadDrawJson = function(flowDrawJson, IsFlow) {
  $('[nodeType]').remove()
  $(flowDrawJson.NodeList).each(function() {
    const nodeItem = this
    var obj = flowObj.CanvasPane[0]
    const cotrolId = nodeItem.nodeId.replace('F_', '')
    let img = 'DrawNode.gif'
    switch (nodeItem.nodeType) {
      case 'SubFlow':
        img = 'DrawSubFlow.gif'
        break
      case 'Node':
        img = 'DrawNode.gif'
        break
      case 'HL':
        img = 'DrawHL.gif'
        break
      case 'FL':
        img = 'DrawFL.gif'
        break
      case 'Start':
        img = 'Start1.gif'
        break
      case 'End':
        img = 'End.gif'
        break
    }
    const nodetop =
      IsFlow == true
        ? parseInt(nodeItem.nodeY.replace('px', '')) + topheight
        : nodeItem.nodeY.replace('px', '')
    var obj = $(
      "<div nodeType='" +
        nodeItem.nodeType +
        "' id='F_" +
        cotrolId +
        "' caption='' style='cursor:pointer; position:absolute;z-index:103;left:" +
        nodeItem.nodeX +
        ';top:' +
        nodetop +
        "px;width:38px;' stroked='f' strokecolor='#000000' strokeweight='1px'  selected='false' ></div>"
    )
    obj.html(
      "<TABLE id='t_" +
        obj.attr('id') +
        '\' cellSpacing=0 cellPadding=0 width="100%" height="100%" border=0><tr height=38px><td Align=center id=\'Image' +
        obj.attr('id') +
        "' style='background:url(\"Content/flow/images/" +
        img +
        "\") '>&nbsp;</td></tr></TABLE><div style='font-size: 11px;position: relative;width: 60px;left: -10px;' id='Text" +
        obj.attr('id') +
        "' align='center'>" +
        nodeItem.nodeText +
        '</div>'
    )
    flowObj.CanvasPane.append(obj)
    if (isFlowDrawReadonly != true) {
      flowObj.NodeBindEvent(obj)
    }
  })
  $(flowDrawJson.LineList).each(function() {
    const nodeItem = this
    const oPolyLine = flowObj.createTag('polyline', {
      fill: 'none',
      stroke: '#3892D3',
      'stroke-width': '2',
      nodeType: nodeItem.nodeType,
      startNode: nodeItem.startNode,
      endNode: nodeItem.endNode,
      points: nodeItem.points,
      'marker-end': 'url(#markerArrow)', /// 目前IE不兼容 这种方式  IE的情况需要注释
      id: nodeItem.lineId
    })
    flowObj.CanvasDraw.append(oPolyLine)
    if (isFlowDrawReadonly != true) {
      $(oPolyLine).click(function() {
        if (flowObj.SelectButtonType == 'MultipleSelect') {
          const contorl = $(this)
          if (contorl.length == 0) {
            flowObj.SelectButtonType = ''
            selectChangedObject = []
            $('rect').remove()
          } else {
            let isChanged = false
            for (let idex = 0; idex < selectChangedObject.length; idex++) {
              if (
                $(selectChangedObject[idex]).attr('id') == $(contorl).attr('id')
              ) {
                isChanged = true
              }
            }
            if (!isChanged) {
              $this.SelectButtonType = ''
              selectChangedObject = []
              $('rect').remove()
            }
          }
        }

        if ($("[SubsidiaryID='" + $(this).attr('id') + "']").length == 0) {
          $('rect').remove()
        }
        if (queryUrlParam('view') != '1') {
          flowObj.CreateLineSubsidiary(this)
        }
      })
    }
  })
}
/// 创建线条
FlowDraw.prototype.CreateLine = function(startID, endID) {
  const startposition = $('#' + startID).position()
  startposition.left = startposition.left + 19
  startposition.top = startposition.top + 19
  const endposition = this.Distance(startposition, endID)
  const points = []
  points.push(startposition.left)
  points.push(startposition.top)
  points.push(endposition.x)
  points.push(endposition.y)
  const oPolyLine = flowObj.createTag('polyline', {
    fill: 'none',
    stroke: '#3892D3',
    'stroke-width': '2',
    nodeType: 'Line',
    startNode: startID,
    endNode: endID,
    points: points.join(','),
    'marker-end': 'url(#markerArrow)', /// 目前IE不兼容 这种方式  IE的情况需要注释
    id: this.GetID()
  })
  flowObj.CanvasDraw.append(oPolyLine)
  $(oPolyLine).click(function() {
    if (flowObj.SelectButtonType == 'MultipleSelect') {
      const contorl = $(this)
      if (contorl.length == 0) {
        flowObj.SelectButtonType = ''
        selectChangedObject = []
        $('rect').remove()
      } else {
        let isChanged = false
        for (let idex = 0; idex < selectChangedObject.length; idex++) {
          if (
            $(selectChangedObject[idex]).attr('id') == $(contorl).attr('id')
          ) {
            isChanged = true
          }
        }
        if (!isChanged) {
          $this.SelectButtonType = ''
          selectChangedObject = []
          $('rect').remove()
        }
      }
    }

    if ($("[SubsidiaryID='" + $(this).attr('id') + "']").length == 0) {
      $('rect').remove()
    }
    if (queryUrlParam('view') != '1') {
      flowObj.CreateLineSubsidiary(this)
    }
  })
}
/// 修改线条
FlowDraw.prototype.ChangedLine = function(startID, endID, updateEndID) {
  const line = $("[startNode='" + startID + "'][endNode='" + endID + "']")
  const points = line
    .attr('points')
    .replace(/ /g, ',')
    .split(',')
  const startP = { x: points[points.length - 4], y: points[points.length - 3] }
  const newp = this.Distance(startP, updateEndID)
  points[points.length - 2] = newp.x
  points[points.length - 1] = newp.y
  line[0].setAttribute('points', points.join(','))
}
/// 删除线条
FlowDraw.prototype.DelLine = function(startID, endID) {
  $("[startNode='" + startID + "'][endNode='" + endID + "']").remove()
}
FlowDraw.prototype.ShowCompletedNode = function(fprocessinsid) {
  if (flowObj.isShowCompletedNode != true) {
    if (processFlow.ProcInsID == '') {
      $('#ImageF_Start').css(
        'background-image',
        'url(Content/flow/images/yellow/DrawCn.gif)'
      )
    } else {
      AJAXAPI(
        '/tappActins/getCompletedNodeList?fprocessinsid=' + fprocessinsid,
        {},
        function(d) {
          if (d.length > 0) {
            $('#ImageF_Start').css(
              'background-image',
              'url(Content/flow/images/green/DrawCn.gif)'
            )
          }
          for (let i = 0; i < d.length; i++) {
            const item = d[i]
            if (item.fstatus == 0 || item.fstatus == 1) {
              $('#Image' + item.factchartid).css(
                'background-image',
                'url(Content/flow/images/yellow/DrawNode.gif)'
              )
            } else {
              // if (item.factchartid == "F_Start") {
              //    $("#Image" + item.factchartid).css("background-image", "url(../Content/flow/images/green/DrawCn.gif)");
              // } else {
              $('#Image' + item.factchartid).css(
                'background-image',
                'url(Content/flow/images/green/DrawNode.gif)'
              )
              // }
            }
          }
        }
      )
    }
  }
}
